
package com.be.beadmin.project.impl;

import cn.hutool.core.util.ObjectUtil;
import com.be.beadmin.common.entity.PageEntity;
import com.be.beadmin.common.exception.BeadminException;
import com.be.beadmin.common.utils.JpaQueryBuilder;
import com.be.beadmin.common.utils.JpaSortBuilder;
import com.be.beadmin.project.dto.input.InfoAndPage;
import com.be.beadmin.project.dto.input.ProductInfoDto;
import com.be.beadmin.project.dto.output.ProductInfoEx;
import com.be.beadmin.project.entity.BatchProduct;
import com.be.beadmin.project.entity.Info;
import com.be.beadmin.project.entity.ProductInfo;
import com.be.beadmin.project.entity.ProductInfo_;
import com.be.beadmin.project.mapper.ProductInfoMapper;
import com.be.beadmin.project.mapper.ProductInfoMapperEx;
import com.be.beadmin.project.repository.BatchProductRepository;
import com.be.beadmin.project.repository.InfoRepository;
import com.be.beadmin.project.repository.ProductInfoRepository;
import com.be.beadmin.project.service.BatchProductService;
import com.be.beadmin.project.service.ProductInfoService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.math3.stat.descriptive.summary.Product;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.Order;
import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.function.Function;

/**
 * @author zjm
 * @description 服务实现
 * @date 2023-02-13
 **/
@Service
@RequiredArgsConstructor
public class ProductInfoServiceImpl implements ProductInfoService {

    @Autowired
    private ProductInfoRepository productInfoRepository;
    @Autowired
    private ProductInfoMapper productInfoMapper;
    @Autowired
    private ProductInfoMapperEx productInfoExMapper;
    @Autowired
    private BatchProductRepository batchProductRepository;

    @Autowired
    private InfoRepository infoRepository;
    @Autowired
    private BatchProductService batchProductService;


    @Override
    public Page<ProductInfoEx> getProductInfoByPage(PageEntity pageEntity) {
        Pageable pageable = PageRequest.of(
                pageEntity.getCurrent() - 1,
                pageEntity.getPageSize());
        Page<ProductInfo> page = productInfoRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
                    List<Predicate> list = new ArrayList<>();
                    Predicate pre1 = JpaQueryBuilder.getPredicate(root, pageEntity.getFilters(), criteriaBuilder);
                    list.add(pre1);
                    Predicate pre2 = criteriaBuilder.equal(root.get(ProductInfo_.delete), 0); //过滤为0
                    list.add(pre2);
                    Predicate[] p = new Predicate[list.size()];
                    List<Order> orders = new ArrayList<>();
                    if (pageEntity.getSorters() != null && pageEntity.getSorters().size() > 0) {
                        orders = JpaSortBuilder.getPredicate(root, pageEntity.getSorters(), criteriaBuilder);
                        criteriaQuery.orderBy(orders);
                    } else {
                        criteriaQuery.orderBy(criteriaBuilder.desc(root.get(ProductInfo_.createTime).as(Date.class)));
                    }
                    return criteriaBuilder.and(list.toArray(p));
                }
                , pageable);
        Page<ProductInfoEx> page1 = page.map(productInfoExMapper::toEntity);
        return page1.map(productInfoEx -> {
            BatchProduct batchProduct = batchProductRepository.findBatchProductByProductCodeAndDelete(productInfoEx.getProductCode(), 0);
            if(batchProduct == null ) {

                productInfoRepository.deleteProductInfoById(1,productInfoEx.getId());
            } else {
                productInfoEx.setState(batchProduct.getState());
                productInfoEx.setReviewState(batchProduct.getReviewState());
            }
            return productInfoEx;
        });


    }

    @Override
    public void addProductInfo(ProductInfoDto productInfoDto) {
        ProductInfo result = productInfoRepository.findProductInfoByIdAndDelete(productInfoDto.getId(), 0);
        Info info = infoRepository.findInfoByIdAndDelete(productInfoDto.getId(), 0);
        productInfoDto.setProjectName(info.getProjectName());
        if (ObjectUtil.isNotEmpty(result)) {
            throw new BeadminException("ProductInfo不存在,请重新查询");
        }
        ProductInfo productInfo = productInfoMapper.toEntity(productInfoDto);
        productInfoRepository.save(productInfo);
    }


    @Override
    public int delProductInfo(String id) {
        ProductInfo productInfo = productInfoRepository.findProductInfoById(id);
//        if (productInfo.getIsPublished()==1){
//            return -10;
//        }

        // 删除批次柜体
        BatchProduct batchProduct = batchProductRepository.findBatchProductByProductCodeAndDelete(productInfo.getProductCode(), 0);
        if (batchProduct == null) {
            productInfo.setDelete(1);
        } else if (batchProduct.getState() == 0) {
            batchProduct.setDelete(1);
            batchProductRepository.save(batchProduct);
        } else {
            return -11; // 柜体已经下发了，无法删除
        }
        productInfo.setDelete(1);
        productInfoRepository.save(productInfo);
        return 0;
    }

    @Override
    public void delProductInfos(List<String> ids) {
    }


    /**
     * 根据项目ID分页获取柜体信息
     *
     * @param infoAndPage
     * @return
     */
    @Override
    public Page<ProductInfoEx> getProductInfoByPageAndInfoId(InfoAndPage infoAndPage) {
        PageEntity pageEntity = infoAndPage.getPageEntity();
        String infoId = infoAndPage.getInfoId();
        if (infoId == null) throw new BeadminException("需要指定项目Id");
        Pageable pageable = PageRequest.of(
                pageEntity.getCurrent() - 1,
                pageEntity.getPageSize());
        Page<ProductInfo> page = productInfoRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
                    List<Predicate> list = new ArrayList<>();
                    Predicate pre1 = JpaQueryBuilder.getPredicate(root, pageEntity.getFilters(), criteriaBuilder);
                    list.add(pre1);
                    Predicate pre2 = criteriaBuilder.equal(root.get(ProductInfo_.delete), 0); //过滤为0
                    list.add(pre2);
                    Predicate pre3 = criteriaBuilder.equal(root.get(ProductInfo_.infoId), infoId); //过滤为0
                    list.add(pre3);
                    Predicate[] p = new Predicate[list.size()];
                    List<Order> orders = new ArrayList<>();
                    if (pageEntity.getSorters() != null && pageEntity.getSorters().size() > 0) {
                        orders = JpaSortBuilder.getPredicate(root, pageEntity.getSorters(), criteriaBuilder);
                        criteriaQuery.orderBy(orders);
                    } else {
                        criteriaQuery.orderBy(criteriaBuilder.desc(root.get(ProductInfo_.createTime).as(Date.class)));
                    }
                    return criteriaBuilder.and(list.toArray(p));
                }
                , pageable);
        Page<ProductInfoEx> page1 = page.map(productInfoExMapper::toEntity);
        return page1.map(productInfoEx -> {
            BatchProduct batchProduct = batchProductRepository.findBatchProductByProductCodeAndDelete(productInfoEx.getProductCode(), 0);
            if(batchProduct == null ) {

                productInfoRepository.deleteProductInfoById(1,productInfoEx.getId());
            } else {
                productInfoEx.setState(batchProduct.getState());
                productInfoEx.setReviewState(batchProduct.getReviewState());
            }


            return productInfoEx;
        });
    }

    @Override
    public List<ProductInfo> getProductsByProjectName(String projectName) {
        List<ProductInfo> productInfoList = productInfoRepository.findProductInfoByProjectNameAndDelete(projectName , 0);
        return productInfoList;
    }
}
